block2 ハッシュ関数で遊ぼう!
はじめに
ブロックチェーンの重要な要素技術の一つであるハッシュ関数がどんなものなのか、遊びながら学んでみよう! ハッシュ関数はブロックチェーン以外でも多くのソフトウェアやシステムで利用されている技術なので、どのようなものか理解しておくのはきっといろいろなところで役立つはずです!
ハッシュ関数とは何か?
せっかくの勉強会なのでだれか説明おねがいします!!hideyoshi.icon
任意長の入力「メッセージ」から固定長の「ハッシュ値」を出力する関数
https://scrapbox.io/files/63e471d234cd78001b81bb84.png
任意長のメッセージから256ビット(32バイト)のハッシュ値を出力するハッシュ関数
7a85e0ab1d89ae40cdd4873ee304c85b933052d378145e53fef8181d79362535
ハッシュ関数の性質
圧縮関数である
任意長の入力
固定長の出力
一方向性
出力から入力を計算することができない
衝突耐性
SHA-256 の場合は出力が 256bit
同じ出力を見つけるのが非常に難しい
入力は任意長
出力は固定長
入力(メッセージ)が同じであれば、ハッシュ値はいつも同じになる
入力(メッセージ)がほんの少しでも異なると、全く異なるハッシュ値になる
一方向性
メッセージからハッシュ値を計算できるが、ハッシュ値からメッセージを計算することはできない
衝突耐性
異なる入力からは異なる出力が得られる
実際には、入力が任意長であり、出力が固定長なので、必ず同じハッシュ値を出力する異なる入力は存在するはず
しかし、衝突の可能性が無視できるほど低ければ、衝突しないという前提で扱うことができる
弱衝突耐性
あるハッシュ値と同じハッシュ値を出力する異なるメッセージを見つけ出すことが困難である性質
強衝突耐性
ハッシュ値が一致する、異なる2つのメッセージを見つけ出すことが困難である性質
高速に計算可能
ハッシュ値を計算してみよう!
ハッシュ関数の活用
ファイルの改ざんを検知
code:bash
shasum -a 256 debian-11.6.0-amd64-netinst.iso
e482910626b30f9a7de9b0cc142c3d4a079fbfa96110083be1d0b473671ce08d debian-11.6.0-amd64-netinst.iso
400MB近くあるファイルでも高速に計算することができる
その他どんなところで使われているかディスカッションしてみようhideyoshi.icon
git で使っている
パスワードの認証
ブロックチェーン
ひとつ前のブロック
ハッシュの値をつなげていくのにつかっている
ブロックをチェーンしている
マイニング
デジタル署名
Ethereum のアドレス
掲示板でじゃんけん
Scrapbox 上でじゃんけんをしてみよう!
Scrapbox はみんなに公開されている。
グー・チョキ・パーの手を書いたら、手の内がバレてしまうのでゲームにならない。
かといって、全員が同時に息を合わせて Scrapbox に手を書き込むことはできない。
どんな方法をとると、公開されている掲示板でじゃんけんができるか考えてみてください!hideyoshi.icon
ハッシュ関数に入れる
公開鍵暗号で暗号化して、公開鍵で検証
Commit & Reveal
メッセージの内容を明かさずに、ある時点でそのメッセージの内容を知っていたことを証明する方法
Commit
メッセージ + 乱数からハッシュ値を作り、ハッシュ値のみを公開の場所で共有
Reveal
メッセージ + 乱数を公開
メッセージ + 乱数から公開済みのハッシュ値を作ることができるか検証
異なるメッセージから同じハッシュ値を作ることは非常に困難
なぜ乱数が必要なのか?
入力(メッセージ)が同じであれば、ハッシュ値はいつも同じになるため、手がわかっていればハッシュ値を容易に突き止めることができてしまう
グー: e89a7c6ac2925985fd98df094f98a787b6e103d305a810005220b8352f2ae63f
チョキ: 0fd1bfb1f6fe2803f6b4d62a999c30b5bbc978833501f9d7dac6fa07cb8dd86f
パー: 96219fea2b5e3c18213440976138d9a07515bd0de37b1aeada912f68bf522208
よく使われているものについては、あらかじめ対応表を作っておくことができる
辞書攻撃(レインボーテーブル攻撃)
Commit!
僕とじゃんけん!hideyoshi.icon
パーc65640011d86590212b8073bed08f98d7b4c10814b9513cc3b59d2afc8077abc
8d4104eee2ba5ab94d2a268134245de11111bc804fd0f3cf18dfd7225a820ae0
なまえ: ハッシュ値
Masamichi hayashi :d34df5ed2db4198809c417449e0513386c97adb677b6e62bf82845d964e7ef32
tachibana.eth: 103e5d58a117c1b26c6731562ecc3072ccb03bb03859bc54504b0c01c2b44134 Takamichi Tsutsumi: 087a132ba8ea860cf530c9023d75f22e6ce86a02e02a959a31a0e1e50acabcc5
ちょきpa-pa-pa-pa-pa-pa-
Toshiki Nakasone: 02e849e85bfe877461ea78053326347657e220feca78e377152e83133f4ed370
チョキ12345
Dan Yumoto: 1c4072d32710b640818cf7ed45ffd507afe6e7f98d53abfb09d6e50e054bee3e
ayame113: 9b680a6e5130606333c38d7b1836d41ffad7c87e028426036e846cc99efe83a3
Tsubasa Ide: 8d76001916e879be009647bbd257d52982cf757737f3f375458183bbc2b38439
Windy:6e359933ac5944e93e89fb7245c42676a7f06a4e1a72c77a078b0f476a631742
Hiromu Higuchi:3ffbf4fe7cebff59b13b1d90148ffd821ee2d83350d9cb69e7639016478c70a3
shin: abf36805594b1e609bdb88fce4deee72dfc55a1db40e5ccbac1806a446de5d64
チョキ8d03a12c302bc16f31f92335ccd7c9dd7aa31c0523a6a9660df1e6da2a3e103a
Hideaki Hata: 2dac25923a923a9489a11280153c2d1c10c628f82790267937b12384b0213771 Hideaki Hata.icon
Reveal
Blockchain にハッシュ値を書き込もう!
以下のコードを実行
code:writeHash.js
function addHtml() {
$('#container').append(`
<table border="1">
<tr>
<td>message</td>
<td><input type="text" id="message" size="80" /></td>
</tr>
</table>
<button onclick="writeHash()">write</button>
`)
}
async function writeHash() {
const message = new TextEncoder("utf-8").encode($("#message").val())
const hash = await crypto.subtle.digest("SHA-256", message)
const transactionParameters = {
to: ethereum.selectedAddress,
from: ethereum.selectedAddress,
data: "0x" + buf2hexStr(hash)
}
const txHash = await ethereum.request({
method: 'eth_sendTransaction',
})
console.log(txHash)
}
function buf2hexStr(buffer) {
return Array.from(new Uint8Array(buffer))
.map(x => x.toString(16).padStart(2, "0"))
.join("")
}
async function connectMetaMask() {
if (typeof window.ethereum === 'undefined') {
console.log('MetaMask がインストールされていません。')
}
const acccounts = await window.ethereum.request({ method: 'eth_requestAccounts' });
if (acccounts.length > 0) {
}
}
(async () => {
await loadScript("./libs/jquery/jquery-3.6.3.min.js")
await loadScript("./libs/ethers/ethers-5.2.umd.min.js")
addHtml()
connectMetaMask()
})()